<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="highlight.js"></script></head><body><pre><span class="hs-pragma">{-# LANGUAGE Trustworthy #-}</span><span>
</span><span id="line-2"></span><span class="hs-pragma">{-# LANGUAGE MagicHash #-}</span><span>
</span><span id="line-3"></span><span>
</span><span id="line-4"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-5"></span><span class="hs-comment">-- |</span><span>
</span><span id="line-6"></span><span class="hs-comment">-- Module      :  Data.Unique</span><span>
</span><span id="line-7"></span><span class="hs-comment">-- Copyright   :  (c) The University of Glasgow 2001</span><span>
</span><span id="line-8"></span><span class="hs-comment">-- License     :  BSD-style (see the file libraries/base/LICENSE)</span><span>
</span><span id="line-9"></span><span class="hs-comment">--</span><span>
</span><span id="line-10"></span><span class="hs-comment">-- Maintainer  :  libraries@haskell.org</span><span>
</span><span id="line-11"></span><span class="hs-comment">-- Stability   :  experimental</span><span>
</span><span id="line-12"></span><span class="hs-comment">-- Portability :  non-portable</span><span>
</span><span id="line-13"></span><span class="hs-comment">--</span><span>
</span><span id="line-14"></span><span class="hs-comment">-- An abstract interface to a unique symbol generator.</span><span>
</span><span id="line-15"></span><span class="hs-comment">--</span><span>
</span><span id="line-16"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-17"></span><span>
</span><span id="line-18"></span><span class="hs-keyword">module</span><span> </span><span class="hs-identifier">Data.Unique</span><span> </span><span class="hs-special">(</span><span>
</span><span id="line-19"></span><span>   </span><span class="annot"><span class="hs-comment">-- * Unique objects</span></span><span>
</span><span id="line-20"></span><span>   </span><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier">Unique</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-21"></span><span>   </span><span class="annot"><a href="Data.Unique.html#newUnique"><span class="hs-identifier">newUnique</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-22"></span><span>   </span><span class="annot"><a href="Data.Unique.html#hashUnique"><span class="hs-identifier">hashUnique</span></a></span><span>
</span><span id="line-23"></span><span> </span><span class="hs-special">)</span><span> </span><span class="hs-keyword">where</span><span>
</span><span id="line-24"></span><span>
</span><span id="line-25"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="System.IO.Unsafe.html"><span class="hs-identifier">System.IO.Unsafe</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.IO.Unsafe.html#unsafePerformIO"><span class="hs-identifier">unsafePerformIO</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-26"></span><span>
</span><span id="line-27"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Num.html"><span class="hs-identifier">GHC.Num</span></a></span><span>
</span><span id="line-28"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="Data.IORef.html"><span class="hs-identifier">Data.IORef</span></a></span><span>
</span><span id="line-29"></span><span>
</span><span id="line-30"></span><span class="hs-comment">-- | An abstract unique object.  Objects of type 'Unique' may be</span><span>
</span><span id="line-31"></span><span class="hs-comment">-- compared for equality and ordering and hashed into 'Int'.</span><span>
</span><span id="line-32"></span><span class="hs-comment">--</span><span>
</span><span id="line-33"></span><span class="hs-comment">-- &gt;&gt;&gt; :{</span><span>
</span><span id="line-34"></span><span class="hs-comment">-- do x &lt;- newUnique</span><span>
</span><span id="line-35"></span><span class="hs-comment">--    print (x == x)</span><span>
</span><span id="line-36"></span><span class="hs-comment">--    y &lt;- newUnique</span><span>
</span><span id="line-37"></span><span class="hs-comment">--    print (x == y)</span><span>
</span><span id="line-38"></span><span class="hs-comment">-- :}</span><span>
</span><span id="line-39"></span><span class="hs-comment">-- True</span><span>
</span><span id="line-40"></span><span class="hs-comment">-- False</span><span>
</span><span id="line-41"></span><span class="hs-keyword">newtype</span><span> </span><span id="Unique"><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-var">Unique</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="Unique"><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-var">Unique</span></a></span></span><span> </span><span class="annot"><a href="../../ghc-bignum/src/GHC.Num.Integer.html#Integer"><span class="hs-identifier hs-type">Integer</span></a></span><span> </span><span class="hs-keyword">deriving</span><span> </span><span class="hs-special">(</span><span id="local-6989586621679565473"><span id="local-6989586621679565478"><span class="annot"><span class="annottext">Unique -&gt; Unique -&gt; Bool
(Unique -&gt; Unique -&gt; Bool)
-&gt; (Unique -&gt; Unique -&gt; Bool) -&gt; Eq Unique
forall a. (a -&gt; a -&gt; Bool) -&gt; (a -&gt; a -&gt; Bool) -&gt; Eq a
/= :: Unique -&gt; Unique -&gt; Bool
$c/= :: Unique -&gt; Unique -&gt; Bool
== :: Unique -&gt; Unique -&gt; Bool
$c== :: Unique -&gt; Unique -&gt; Bool
</span><a href="../../ghc-prim/src/GHC.Classes.html#Eq"><span class="hs-identifier hs-var hs-var hs-var hs-var hs-var hs-var">Eq</span></a></span></span></span><span class="hs-special">,</span><span id="local-6989586621679565440"><span id="local-6989586621679565444"><span id="local-6989586621679565448"><span id="local-6989586621679565452"><span id="local-6989586621679565456"><span id="local-6989586621679565460"><span id="local-6989586621679565465"><span class="annot"><span class="annottext">Eq Unique
Eq Unique
-&gt; (Unique -&gt; Unique -&gt; Ordering)
-&gt; (Unique -&gt; Unique -&gt; Bool)
-&gt; (Unique -&gt; Unique -&gt; Bool)
-&gt; (Unique -&gt; Unique -&gt; Bool)
-&gt; (Unique -&gt; Unique -&gt; Bool)
-&gt; (Unique -&gt; Unique -&gt; Unique)
-&gt; (Unique -&gt; Unique -&gt; Unique)
-&gt; Ord Unique
Unique -&gt; Unique -&gt; Bool
Unique -&gt; Unique -&gt; Ordering
Unique -&gt; Unique -&gt; Unique
forall a.
Eq a
-&gt; (a -&gt; a -&gt; Ordering)
-&gt; (a -&gt; a -&gt; Bool)
-&gt; (a -&gt; a -&gt; Bool)
-&gt; (a -&gt; a -&gt; Bool)
-&gt; (a -&gt; a -&gt; Bool)
-&gt; (a -&gt; a -&gt; a)
-&gt; (a -&gt; a -&gt; a)
-&gt; Ord a
min :: Unique -&gt; Unique -&gt; Unique
$cmin :: Unique -&gt; Unique -&gt; Unique
max :: Unique -&gt; Unique -&gt; Unique
$cmax :: Unique -&gt; Unique -&gt; Unique
&gt;= :: Unique -&gt; Unique -&gt; Bool
$c&gt;= :: Unique -&gt; Unique -&gt; Bool
&gt; :: Unique -&gt; Unique -&gt; Bool
$c&gt; :: Unique -&gt; Unique -&gt; Bool
&lt;= :: Unique -&gt; Unique -&gt; Bool
$c&lt;= :: Unique -&gt; Unique -&gt; Bool
&lt; :: Unique -&gt; Unique -&gt; Bool
$c&lt; :: Unique -&gt; Unique -&gt; Bool
compare :: Unique -&gt; Unique -&gt; Ordering
$ccompare :: Unique -&gt; Unique -&gt; Ordering
</span><a href="../../ghc-prim/src/GHC.Classes.html#Ord"><span class="hs-identifier hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var hs-var">Ord</span></a></span></span></span></span></span></span></span></span><span class="hs-special">)</span><span>
</span><span id="line-42"></span><span>
</span><span id="line-43"></span><span class="annot"><a href="Data.Unique.html#uniqSource"><span class="hs-identifier hs-type">uniqSource</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.IORef.html#IORef"><span class="hs-identifier hs-type">IORef</span></a></span><span> </span><span class="annot"><a href="../../ghc-bignum/src/GHC.Num.Integer.html#Integer"><span class="hs-identifier hs-type">Integer</span></a></span><span>
</span><span id="line-44"></span><span id="uniqSource"><span class="annot"><span class="annottext">uniqSource :: IORef Integer
</span><a href="Data.Unique.html#uniqSource"><span class="hs-identifier hs-var hs-var">uniqSource</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">IO (IORef Integer) -&gt; IORef Integer
forall a. IO a -&gt; a
</span><a href="GHC.IO.Unsafe.html#unsafePerformIO"><span class="hs-identifier hs-var">unsafePerformIO</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">Integer -&gt; IO (IORef Integer)
forall a. a -&gt; IO (IORef a)
</span><a href="GHC.IORef.html#newIORef"><span class="hs-identifier hs-var">newIORef</span></a></span><span> </span><span class="annot"><span class="annottext">Integer
</span><span class="hs-number">0</span></span><span class="hs-special">)</span><span>
</span><span id="line-45"></span><span class="hs-pragma">{-# NOINLINE</span><span> </span><span class="annot"><a href="Data.Unique.html#uniqSource"><span class="hs-pragma hs-type">uniqSource</span></a></span><span> </span><span class="hs-pragma">#-}</span><span>
</span><span id="line-46"></span><span>
</span><span id="line-47"></span><span class="hs-comment">-- | Creates a new object of type 'Unique'.  The value returned will</span><span>
</span><span id="line-48"></span><span class="hs-comment">-- not compare equal to any other value of type 'Unique' returned by</span><span>
</span><span id="line-49"></span><span class="hs-comment">-- previous calls to 'newUnique'.  There is no limit on the number of</span><span>
</span><span id="line-50"></span><span class="hs-comment">-- times 'newUnique' may be called.</span><span>
</span><span id="line-51"></span><span class="annot"><a href="Data.Unique.html#newUnique"><span class="hs-identifier hs-type">newUnique</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#IO"><span class="hs-identifier hs-type">IO</span></a></span><span> </span><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-type">Unique</span></a></span><span>
</span><span id="line-52"></span><span id="newUnique"><span class="annot"><span class="annottext">newUnique :: IO Unique
</span><a href="Data.Unique.html#newUnique"><span class="hs-identifier hs-var hs-var">newUnique</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-keyword">do</span><span>
</span><span id="line-53"></span><span>  </span><span id="local-6989586621679565433"><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565433"><span class="hs-identifier hs-var">r</span></a></span></span><span> </span><span class="hs-glyph">&lt;-</span><span> </span><span class="annot"><span class="annottext">IORef Integer -&gt; (Integer -&gt; (Integer, Integer)) -&gt; IO Integer
forall a b. IORef a -&gt; (a -&gt; (a, b)) -&gt; IO b
</span><a href="GHC.IORef.html#atomicModifyIORef%27"><span class="hs-identifier hs-var">atomicModifyIORef'</span></a></span><span> </span><span class="annot"><span class="annottext">IORef Integer
</span><a href="Data.Unique.html#uniqSource"><span class="hs-identifier hs-var">uniqSource</span></a></span><span> </span><span class="annot"><span class="annottext">((Integer -&gt; (Integer, Integer)) -&gt; IO Integer)
-&gt; (Integer -&gt; (Integer, Integer)) -&gt; IO Integer
forall a b. (a -&gt; b) -&gt; a -&gt; b
</span><a href="GHC.Base.html#%24"><span class="hs-operator hs-var">$</span></a></span><span> </span><span class="hs-glyph">\</span><span id="local-6989586621679565431"><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565431"><span class="hs-identifier hs-var">x</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-keyword">let</span><span> </span><span id="local-6989586621679565428"><span class="annot"><span class="annottext">z :: Integer
</span><a href="#local-6989586621679565428"><span class="hs-identifier hs-var hs-var">z</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565431"><span class="hs-identifier hs-var">x</span></a></span><span class="annot"><span class="annottext">Integer -&gt; Integer -&gt; Integer
forall a. Num a =&gt; a -&gt; a -&gt; a
</span><a href="GHC.Num.html#%2B"><span class="hs-operator hs-var">+</span></a></span><span class="annot"><span class="annottext">Integer
</span><span class="hs-number">1</span></span><span> </span><span class="hs-keyword">in</span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565428"><span class="hs-identifier hs-var">z</span></a></span><span class="hs-special">,</span><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565428"><span class="hs-identifier hs-var">z</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-54"></span><span>  </span><span class="annot"><span class="annottext">Unique -&gt; IO Unique
forall (m :: * -&gt; *) a. Monad m =&gt; a -&gt; m a
</span><a href="GHC.Base.html#return"><span class="hs-identifier hs-var">return</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">Integer -&gt; Unique
</span><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-var">Unique</span></a></span><span> </span><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565433"><span class="hs-identifier hs-var">r</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-55"></span><span>
</span><span id="line-56"></span><span class="hs-comment">-- SDM (18/3/2010): changed from MVar to STM.  This fixes</span><span>
</span><span id="line-57"></span><span class="hs-comment">--  1. there was no async exception protection</span><span>
</span><span id="line-58"></span><span class="hs-comment">--  2. there was a space leak (now new value is strict)</span><span>
</span><span id="line-59"></span><span class="hs-comment">--  3. using atomicModifyIORef would be slightly quicker, but can</span><span>
</span><span id="line-60"></span><span class="hs-comment">--     suffer from adverse scheduling issues (see #3838)</span><span>
</span><span id="line-61"></span><span class="hs-comment">--  4. also, the STM version is faster.</span><span>
</span><span id="line-62"></span><span>
</span><span id="line-63"></span><span class="hs-comment">-- SDM (30/4/2012): changed to IORef using atomicModifyIORef.  Reasons:</span><span>
</span><span id="line-64"></span><span class="hs-comment">--  1. STM version could not be used inside unsafePerformIO, if it</span><span>
</span><span id="line-65"></span><span class="hs-comment">--     happened to be poked inside an STM transaction.</span><span>
</span><span id="line-66"></span><span class="hs-comment">--  2. IORef version can be used with unsafeIOToSTM inside STM,</span><span>
</span><span id="line-67"></span><span class="hs-comment">--     because if the transaction retries then we just get a new</span><span>
</span><span id="line-68"></span><span class="hs-comment">--     Unique.</span><span>
</span><span id="line-69"></span><span class="hs-comment">--  3. IORef version is very slightly faster.</span><span>
</span><span id="line-70"></span><span>
</span><span id="line-71"></span><span class="hs-comment">-- IGL (08/06/2013): changed to using atomicModifyIORef' instead.</span><span>
</span><span id="line-72"></span><span class="hs-comment">--  This feels a little safer, from the point of view of not leaking</span><span>
</span><span id="line-73"></span><span class="hs-comment">--  memory, but the resulting core is identical.</span><span>
</span><span id="line-74"></span><span>
</span><span id="line-75"></span><span class="hs-comment">-- | Hashes a 'Unique' into an 'Int'.  Two 'Unique's may hash to the</span><span>
</span><span id="line-76"></span><span class="hs-comment">-- same value, although in practice this is unlikely.  The 'Int'</span><span>
</span><span id="line-77"></span><span class="hs-comment">-- returned makes a good hash key.</span><span>
</span><span id="line-78"></span><span class="annot"><a href="Data.Unique.html#hashUnique"><span class="hs-identifier hs-type">hashUnique</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-type">Unique</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#Int"><span class="hs-identifier hs-type">Int</span></a></span><span>
</span><span id="line-79"></span><span id="hashUnique"><span class="annot"><span class="annottext">hashUnique :: Unique -&gt; Int
</span><a href="Data.Unique.html#hashUnique"><span class="hs-identifier hs-var hs-var">hashUnique</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="Data.Unique.html#Unique"><span class="hs-identifier hs-type">Unique</span></a></span><span> </span><span id="local-6989586621679565426"><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565426"><span class="hs-identifier hs-var">i</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Integer -&gt; Int
</span><a href="../../ghc-bignum/src/GHC.Num.Integer.html#integerToInt"><span class="hs-identifier hs-var">integerToInt</span></a></span><span> </span><span class="annot"><span class="annottext">Integer
</span><a href="#local-6989586621679565426"><span class="hs-identifier hs-var">i</span></a></span><span>
</span><span id="line-80"></span></pre></body></html>